//
//  CWFData.m
//  Care Wit Friends - DataView
//
//  Created by Kleinfelder, Erik on 11/3/13.
//  Copyright (c) 2013 Kleinfelder, Erik. All rights reserved.
//

#import "CWFData.h"

@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end

@implementation CWFData {
    int heartBeat;
    int CWFAuthStatus;
    
}

@synthesize CWFUserID;
@synthesize CWFAuthtoken;
@synthesize CWFlogin;
@synthesize CWFpassword;
@synthesize currentRequest;
@synthesize CWFemail;

+ (CWFData *)sharedInstance{
    static dispatch_once_t pred;
    static CWFData *sharedInstance = nil;
    dispatch_once(&pred, ^{
        sharedInstance = [[self alloc] init];});
    return sharedInstance;
    
}

- (id)init {
    self = [super init];
    if (self) {
        
        //  TEMPORARY FOR TESTING
        // CWFUserID = 1; // temp
        // CWFAuthtoken = @"taco1";
        // currentRequest = [NSString stringWithFormat:@"allowNewRequest"];
        //  TEMPORARY FOR TESTING (Comment below variable to use above test values)
        
        CWFAuthtoken = @"authNotAttempted";
        CWFBaseURL = @"https://cwf.xcal.tv/care-wit-friends";
        CWFAuthStatus = -1;
        CWFUserQuery = @"";
        currentRequest = [NSString stringWithFormat:@"notAuthenticated"];
        CWFAuthtoken = [[NSString alloc] init];
        CWFUserDetailArray = [[NSMutableArray alloc] init];
        CWFUserFollowers = [[NSMutableArray alloc] init];
        CWFUserFollowedUsers = [[NSMutableArray alloc] init];
        CWFAuthDict = [[NSMutableDictionary alloc] init];
        CWFUserFeedArray = [[NSMutableArray alloc] init];
        CWFFollowingFeedArray = [[NSMutableArray alloc] init];
        CWFInterestedFeedArray = [[NSMutableArray alloc] init];
        CWFGlobalFeedArray = [[NSMutableArray alloc] init];
        CWFGlobalLeaderboardArray = [[NSMutableArray alloc] init];
        CWFFriendsLeaderboardArray = [[NSMutableArray alloc] init];
        CWFGetProblemArray = [[NSMutableArray alloc] init];
        CWFPostFollowUser = [[NSMutableArray alloc] init];
        CWFPostCreateProblem = [[NSMutableArray alloc] init];
        CWFGetSaleArray = [[NSMutableArray alloc] init];
        CWFGetTagListArray = [[NSMutableArray alloc] init];
        CWFGetUsersListArray = [[NSMutableArray alloc] init];
        
        commandQueue = [[NSMutableArray alloc] init];
        
        heartBeatTimer  = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(heartbeatUpdate:) userInfo:nil repeats:YES];
        
    }
    return self;
}
// Intra-App Notificaitons
//
//  observers:
//    - authenticationResponse
//    - dataHasBeenUpdated


// Methods for APP
//
// -(void)CWFLogoout;



//
// Methods to Retrieve Objects for use in display
//

- (NSMutableArray *)getUserDetail {
    return CWFUserDetailArray;
}

- (NSMutableArray *)getUserFollowers {
    return CWFUserFollowers;
}

- (NSMutableArray *)getFollowedUsers {
    return CWFUserFollowedUsers;
}

- (NSMutableArray *)getUserFeed {
    return CWFUserFeedArray;
}

- (NSMutableArray *)getFollowingFeed {
    return CWFFollowingFeedArray;
}

- (NSMutableArray *)getInterestedFeed {
    return CWFInterestedFeedArray;
}

- (NSMutableArray *)getGlobalFeed {
    return CWFGlobalFeedArray;
}

- (NSMutableArray *)getGlobalLeaderboard {
    return CWFGlobalLeaderboardArray;
}

- (NSMutableArray *)getFriendsLeaderboard {
    return CWFFriendsLeaderboardArray;
}

- (NSMutableArray *)getProblem {
    return CWFGetProblemArray;
}

- (NSMutableArray *)getSale {
    return CWFGetSaleArray;
}

- (NSMutableArray *)getTagList {
    return CWFGetTagListArray;
}

- (NSMutableArray *)getUsersList{
    return CWFGetUsersListArray;
}

//
// Methods to update DB with user request
//

-(void)CWFLogout  {
    CWFAuthStatus = -1;
}

- (void) followUser:(NSString *)userToFollow {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:userToFollow forKey:@"id"];
    retValue = [self sendCWFPostRequest:@"followUser" requestDict:tempPostDict];
}

- (void) unfollowUser:(NSString *)userToUnfollow {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:userToUnfollow forKey:@"id"];
    retValue = [self sendCWFPostRequest:@"unfollowUser" requestDict:tempPostDict];
}

- (void) addInterest:(NSString *)interest {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:interest forKey:@"interest"];
    retValue = [self sendCWFPostRequest:@"addInterest" requestDict:tempPostDict];
}

- (void) removeInterest:(NSString *)interest {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:interest forKey:@"interest"];
    retValue = [self sendCWFPostRequest:@"removeInterest" requestDict:tempPostDict];
}

- (void) createProblem:(NSString *)customerName
         customerPhone:(NSString *)customerTN
             custEmail:(NSString *)customerEmail
       custMobilePhone:(NSString *)customerMobileTN
                 title:(NSString *)problemTitle
           description:(NSString *)problemDescription
                  tags:(NSMutableArray *)problemTags {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:customerName forKey:@"customer_name"];
    [tempPostDict setObject:customerTN forKey:@"customer_acct_tn"];
    [tempPostDict setObject:customerEmail forKey:@"customer_email"];
    [tempPostDict setObject:customerMobileTN forKey:@"customer_mobile_tn"];
    [tempPostDict setObject:problemTitle forKey:@"problem_title"];
    [tempPostDict setObject:problemDescription forKey:@"problem_description"];
    [tempPostDict setObject:problemTags forKey:@"problem_tags"];
    retValue = [self sendCWFPostRequest:@"createProblem" requestDict:tempPostDict];
}

- (void) addTagToProblem:(NSString *)tag {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:tag forKey:@"tag"];
    retValue = [self sendCWFPostRequest:@"addTagToProblem" requestDict:tempPostDict];
}

- (void) removeTagFromProblem:(NSString *)tag {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:tag forKey:@"tag"];
    retValue = [self sendCWFPostRequest:@"removeTagFromProblem" requestDict:tempPostDict];
}

- (void) createSale:(NSString *)customerName
      customerPhone:(NSString *)customerTN
          custEmail:(NSString *)customerEmail
    custMobilePhone:(NSString *)customerMobileTN
        description:(NSString *)problemDescription {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:customerName forKey:@"customer_name"];
    [tempPostDict setObject:customerTN forKey:@"customer_acct_tn"];
    [tempPostDict setObject:customerEmail forKey:@"customer_email"];
    [tempPostDict setObject:customerMobileTN forKey:@"customer_mobile_tn"];
    [tempPostDict setObject:problemDescription forKey:@"problem_description"];
    retValue = [self sendCWFPostRequest:@"createSale" requestDict:tempPostDict];
}

- (void) createPost:(NSString *)postBody postIssueNum:(NSString *)postID postType:(NSString *)postSaleOrProblemType {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:postBody forKey:@"body"];
    [tempPostDict setObject:postID forKey:@"postable_id"];
    [tempPostDict setObject:postSaleOrProblemType forKey:@"postable_type"];
    retValue = [self sendCWFPostRequest:@"createPost" requestDict:tempPostDict];
}

- (void) createComment:(NSString *)postBody postIssueNum:(NSString *)postID {
    NSMutableDictionary *tempPostDict;
    int retValue;
    
    // Create Dictionary for delivering data to server
    tempPostDict = [[NSMutableDictionary alloc] init];
    [tempPostDict setObject:postBody forKey:@"body"];
    [tempPostDict setObject:postID forKey:@"postable_id"];
    retValue = [self sendCWFPostRequest:@"createComment" requestDict:tempPostDict];
}

//
// Heartbeat for Database updates...
//
- (void)heartbeatUpdate:(NSTimer *)aTimer {
    
    heartBeat++;
    NSLog(@"Database Sync Heartbeat %d", heartBeat);
    if ([CWFAuthtoken isEqualToString:@"authNotAttempted"]) {
        // Still waiting to authenticate('authNotAttempted' is the initial value of CWFAuthToken and will change on any response from the server)
        NSLog(@"Pending Authentication...");
        return;
    } else if ([CWFAuthtoken isEqualToString:@"authenticationFailed"]) {
        //  DO SOMETHING HERE FOR APP
        NSLog(@"Authenticastion Failed: %@", CWFAuthtoken);
        return;
    }
    [self refreshAllData];
}

//
//
// Methods for parsing server response from JSON to objects
//
//
- (void)handleResponse {
    NSError *error;
    NSMutableDictionary *tempAuthDict;
    NSInteger i, totalCommands;
    NSString *nextRequest, *commandType;
    NSDictionary *nextRequestDict;
    NSMutableDictionary *authData;
    
    NSLog(@"currentRequest: %@     CWFAuthtoken: %@", currentRequest, CWFAuthtoken);
    
    if ([currentRequest isEqualToString:@"attemptingAuth"]) {
        tempAuthDict = [[NSMutableDictionary alloc] init];
        tempAuthDict = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
        NSLog(@"%@", tempAuthDict);
        if ([tempAuthDict objectForKey:@"message"]) {
            if ([[tempAuthDict objectForKey:@"message"] isEqualToString:@"Invalid email or password."]) {
                NSLog(@"Authentication Failed: %@", [tempAuthDict objectForKey:@"message"]);
                CWFAuthtoken = @"authNotAttempted";
                [authData setValue:@"badEmailPass" forKey:@"authentication"];
                [authData setValue:@"E-Mail or Password incorrect" forKey:@"errorText"];
            } else {
                NSLog(@"Unknown authentication error");
                CWFAuthtoken = @"authNotAttempted";
                [authData setValue:@"serverError" forKey:@"authentication"];
                [authData setValue:@"Server Respone Failure, try to login again" forKey:@"errorText"];
            }
            CWFAuthStatus = 0;
            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc postNotificationName:@"authenticationResponse" object:self userInfo:authData];
            return;
        }
        // Read response for Auth Token
        CWFUserID = [[tempAuthDict objectForKey:@"id"] integerValue];
        CWFAuthtoken = [tempAuthDict objectForKey:@"token"];
        CWFAuthStatus = 1;
        // Authentication is complete.  Grab all data for user
        [self refreshAllData];
    } else if ([currentRequest isEqualToString:@"gettingUserDetails"]) {
        // Parse User Details
        NSLog(@"handleResponse 'gettingUserDetails': Mapping JSON to Array");
        CWFUserDetailArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingFollowedUsers"]) {
        NSLog(@"handleResponse 'gettingFollowedUsers': Mapping JSON to Array of Dictionaries");
        CWFUserFollowedUsers = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingUserFollowers"]) {
        NSLog(@"handleResponse 'gettingUserFollowers': Mapping JSON to Array of Dictionaries");
        CWFUserFollowers = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingUserFeeds"]) {
        NSLog(@"handleResponse 'gettingUserFeeds': Mapping JSON to Array");
        CWFUserFeedArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingFollowingFeeds"]) {
        NSLog(@"handleResponse 'gettingFollowingFeeds': Mapping JSON to Array");
        CWFFollowingFeedArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingInterestedFeeds"]) {
        NSLog(@"handleResponse 'gettingInterestedFeeds': Mapping JSON to Array");
        CWFInterestedFeedArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingGlobelFeeds"]) {
        NSLog(@"handleResponse 'gettingGlobelFeeds': Mapping JSON to Array");
        CWFGlobalFeedArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingGlobalLeaderboard"]) {
        NSLog(@"handleResponse 'gettingGlobalLeaderboard': Mapping JSON to Array");
        CWFGlobalLeaderboardArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingFriendsLeaderboard"]) {
        NSLog(@"handleResponse 'gettingFriendsLeaderboard': Mapping JSON to Array");
        CWFFriendsLeaderboardArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingProblem"]) {
        NSLog(@"handleResponse 'gettingProblem': Mapping JSON to Array");
        CWFGetProblemArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"postingFollowUser"]) {
        NSLog(@"handleResponse 'postingFollowUser': Mapping JSON to Array of Dictionaries");
        CWFPostFollowUser = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"postingCreateProblem"]) {
        NSLog(@"handleResponse 'postingCreateProblem': Mapping JSON to Array of Dictionaries");
        CWFPostCreateProblem = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingSale"]) {
        NSLog(@"handleResponse 'gettingSale': Mapping JSON to Array");
        CWFGetSaleArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingTagList"]) {
        NSLog(@"handleResponse 'gettingTagList': Mapping JSON to Array");
        CWFGetTagListArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if ([currentRequest isEqualToString:@"gettingUsersList"]) {
        NSLog(@"handleResponse 'gettingUserList': Mapping JSON to Array");
        CWFGetUsersListArray = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:&error];
    } else if (![CWFAuthtoken isEqualToString:@"authNotAttempted"]) {
        // Authentication has failed  (now what?)
        return;
    } else {
        NSLog(@"handleResponse Method: No direction on how to handle response for request = %@", currentRequest);
    }
    
    
    
    
    NSLog(@"Command Queue Length: %lu", (unsigned long)[commandQueue count]);
    if ([commandQueue count] > 0) {
        // We have commands in the queue that we need to send to the server
        // Pop the next command off the queue, determine the type of command it is (GET or POST) and
        // adjust queue and invoke method to handle next command
        if ([[commandQueue objectAtIndex:0] isKindOfClass:[NSString class]]) {
            // NSString Class (GET command... No arguments]
            commandType = @"string";
            nextRequest = [commandQueue objectAtIndex:0];
            NSLog(@"Next command: %@", nextRequest);
        } else {
            // NSDictionary Class (POST command... need to send arguments)
            commandType = @"dictionary";
            nextRequestDict = [commandQueue objectAtIndex:0];
        }
        
        // Re-order commandQueue
        if ([commandQueue count] == 1) {
            [commandQueue removeAllObjects];
        } else {
            totalCommands = [commandQueue count];
            for (i=0; i < totalCommands - 1; i++) {
                [commandQueue replaceObjectAtIndex:i withObject:[commandQueue objectAtIndex:i+1]];
                NSLog(@"     Moved command: %@ to index %ld", [commandQueue objectAtIndex:i], (long)i);
            }
            [commandQueue removeObjectAtIndex:totalCommands - 1];
            NSLog(@"Total Commands Left: %d", totalCommands - 1);
        }
    } else {
        currentRequest = @"allowNewRequest";
        
    }
    if (![currentRequest isEqualToString:@"allowNewRequest"]) {
        // We have a command that was popped off of the queue.  Let the object know a new equest is allowed and send the command to the server
        currentRequest = @"allowNewRequest";
        if ([commandType isEqualToString:@"string"]) {
            [self sendCWFGetRequest:nextRequest];
        } else {
            // The command type is Dictionary
            [self sendCWFPostRequest:[nextRequestDict objectForKey:@"command"] requestDict:[nextRequestDict objectForKey:@"arguments"]];
        }
    }
    
    NSLog(@"CWFUserID: %ld     CWFAuthtoken: %@", (long)CWFUserID, CWFAuthtoken);
    
    if ((self.authStatus == 1) && ([commandQueue count] == 0)){
        [[NSNotificationCenter defaultCenter] postNotificationName:@"loadingFinished" object:self];
    }
    
    
    return;
}

//
//
// Methods for connecting and pushing/pulling data from the server
//
//

- (void) refreshAllData {
    // DO NOT refresh unless we are authenticated
    if ([CWFAuthtoken isEqualToString:@"authNotAttempted"]) {
        // NOT authenticated, do not refresh
        NSLog(@"refreshAllData:  We are not authenticated, data NOT refreshed");
        return;
    }
    NSLog(@"refreshAllData:  Refreshing all Data from DB");
    //    [self addInterest:@"billing"];
    //    [self removeInterest:@"billing"];
    
    [self sendCWFGetRequest:@"getGlobalFeeds"];
    [self sendCWFGetRequest:@"getFollowedUsers"];
    [self sendCWFGetRequest:@"getUserDetails"];
    [self sendCWFGetRequest:@"getUserFeeds"];
    [self sendCWFGetRequest:@"getUserFollowers"];
    [self sendCWFGetRequest:@"getFollowingFeeds"];
    [self sendCWFGetRequest:@"getInterestedFeeds"];
    [self sendCWFGetRequest:@"getGlobalLeaderboard"];
    [self sendCWFGetRequest:@"getFriendsLeaderboard"];
    [self sendCWFGetRequest:@"getProblem"];
    [self sendCWFGetRequest:@"getSale"];
    [self sendCWFGetRequest:@"getTagList"];
    [self sendCWFGetRequest:@"getUsersList"];
}



- (int) sendCWFGetRequest:(NSString *)CWFRequestString {
    NSURLConnection *conn;
    NSMutableURLRequest *request;
    
    if (([CWFAuthtoken isEqualToString:@"authNotAttempted"]) || ([currentRequest isEqualToString:@"notAuthenticated"])) {
        // Not Authenticated, do not retrieve any data
        return -1;
    }
    NSLog(@"sendCWFGetRequest received the following request: %@", CWFRequestString);
    if (![currentRequest isEqualToString:@"allowNewRequest"]) {
        // We are currently processing a request.  Put latest Request on the queue
        NSLog(@"Server Request in progress, next command -> %@   Queue Length: %lu.  Adding command to queue", CWFRequestString, (unsigned long)[commandQueue count]);
        [commandQueue addObject:CWFRequestString];
        return -2;
    }
    //
    // Determine what are we requesting? And then create the request.
    //
    if ([CWFRequestString isEqualToString:@"getUserDetails"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/%ld?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"gettingUserDetails";
    } else if ([CWFRequestString isEqualToString:@"getUserFollowers"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/%ld/followers?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"gettingUserFollowers";
    } else if ([CWFRequestString isEqualToString:@"getFollowedUsers"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/%ld/following?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"gettingFollowedUsers";
    } else if ([CWFRequestString isEqualToString:@"getUserFeeds"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/feeds/mine?auth_token=%@", CWFBaseURL, CWFAuthtoken]]];
        currentRequest = @"gettingUserFeeds";
    } else if ([CWFRequestString isEqualToString:@"getFollowingFeeds"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/feeds/following?auth_token=%@", CWFBaseURL, CWFAuthtoken]]];
        currentRequest = @"gettingFollowingFeeds";
    } else if ([CWFRequestString isEqualToString:@"getInterestedFeeds"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/feeds/interested_in?auth_token=%@", CWFBaseURL, CWFAuthtoken]]];
        currentRequest = @"gettingInterestedFeeds";
    } else if ([CWFRequestString isEqualToString:@"getGlobalLeaderboard"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/leaderboards/global", CWFBaseURL]]];
        currentRequest = @"gettingGlobalLeaderboard";
    } else if ([CWFRequestString isEqualToString:@"getFriendsLeaderboard"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/leaderboards/friends", CWFBaseURL]]];
        currentRequest = @"gettingFriendsLeaderboard";
    } else if ([CWFRequestString isEqualToString:@"getGlobalFeeds"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/feeds/global?auth_token=%@", CWFBaseURL, CWFAuthtoken]]];
        currentRequest = @"gettingGlobelFeeds";
    } else if ([CWFRequestString isEqualToString:@"getProblem"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/problems/%ld?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"gettingProblem";
    } else if ([CWFRequestString isEqualToString:@"getSale"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/sales/%ld?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"gettingSale";
    } else if ([CWFRequestString isEqualToString:@"getTagList"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/tags?auth_token=%@", CWFBaseURL, CWFAuthtoken]]];
        currentRequest = @"gettingTagList";
    } else if ([CWFRequestString isEqualToString:@"getUsersList"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/search?auth_token=%@&query=%@", CWFBaseURL, CWFAuthtoken, CWFUserQuery]]];
        currentRequest = @"gettingUsersList";
    }
    NSLog(@"sendCWFGetRequest 'currentRequest' = %@", currentRequest);
    
    
    // Specify that it will be a GET request
    [request setHTTPMethod:@"GET"];
    
    // This is how we set header fields
    // [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-type"];
    
    // Fire request
    conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    return 1;
}

- (int) sendCWFPostRequest:(NSString *)CWFPostString requestDict:(NSDictionary *)CWFPostRequestDict {
    NSURLConnection *conn;
    NSMutableURLRequest *request;
    int count = 0;
    
    if (([CWFAuthtoken isEqualToString:@"authNotAttempted"]) || ([currentRequest isEqualToString:@"notAuthenticated"])) {
        // Not Authenticated, do not retrieve any data
        return -1;
    }
    NSLog(@"sendCWFPostRequest received the following request: %@", CWFPostString);
    if (![currentRequest isEqualToString:@"allowNewRequest"]) {
        NSMutableDictionary *tempCommandDict;
        // We are currently processing a request.  Put latest Request on the queue (This is a different type of Queued command as it has arguments,
        // so we will create a dictionary object and push that onto the commandQueue
        NSLog(@"Server Request in progress, next command -> %@   Queue Length: %lu.  Adding command to queue", CWFPostString, (unsigned long)[commandQueue count]);
        tempCommandDict = [[NSMutableDictionary alloc] init];
        [tempCommandDict setObject:CWFPostString forKey:@"command"];
        [tempCommandDict setObject:CWFPostRequestDict forKey:@"arguments"];
        [commandQueue addObject:tempCommandDict];
        return -2;
    }
    
    //
    // Determine what are we requesting? And then create the request.
    //
    if ([CWFPostString isEqualToString:@"followUser"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/follow", CWFBaseURL]]];
        currentRequest = @"postingFollowUser";
    } else if ([CWFPostString isEqualToString:@"unfollowUser"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/unfollow", CWFBaseURL]]];
        currentRequest = @"postingUnfollowUser";
    } else if ([CWFPostString isEqualToString:@"createProblem"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/problems", CWFBaseURL]]];
        currentRequest = @"postingCreateProblem";
    } else if ([CWFPostString isEqualToString:@"createPost"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/posts", CWFBaseURL]]];
        currentRequest = @"postingCreatePost";
    } else if ([CWFPostString isEqualToString:@"createComment"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/comments", CWFBaseURL]]];
        currentRequest = @"postingCreateComment";
    } else if ([CWFPostString isEqualToString:@"addInterest"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/%ld/add_interest?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"postingAddInterest";
    } else if ([CWFPostString isEqualToString:@"removeInterest"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/users/%ld/remove_interest?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"postingRemoveInterest";
    } else if ([CWFPostString isEqualToString:@"addTagToProblem"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/problems/%ld/add_tag?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"postingAddTagToProblem";
    } else if ([CWFPostString isEqualToString:@"removeTagFromProblem"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/problems/%ld/remove_tag?auth_token=%@", CWFBaseURL, (long)CWFUserID, CWFAuthtoken]]];
        currentRequest = @"postingRemoveTagFromProblem";
    } else if ([CWFPostString isEqualToString:@"createSale"]) {
        request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/api/v1/sales", CWFBaseURL]]];
        currentRequest = @"postingCreateSale";
    }
    
    
    
    NSLog(@"sendCWFPostRequest 'currentRequest' = %@", currentRequest);
    
    // Specify that it will be a POST request
    [request setHTTPMethod:@"POST"];
    
    // This is how we set header fields
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-type"];
    
    // Convert your data and set your request's HTTPBody property
    NSString *stringData = [NSString stringWithFormat:@"{\"auth_token\":\"%@\", ", CWFAuthtoken];
    for(id key in CWFPostRequestDict) {
        if (count) {
            stringData = [stringData stringByAppendingFormat:@", "];
        }
        NSLog(@"key=%@ value=%@", key, [CWFPostRequestDict objectForKey:key]);
        stringData = [stringData stringByAppendingFormat:@"\"%@\":\"%@\"", key, [CWFPostRequestDict objectForKey:key]];
        count++;
    }
    stringData = [stringData stringByAppendingFormat:@"}"];
    NSLog(@"%@", stringData);
    NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:requestBodyData];
    // Fire request
    conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    
    return 1;
}

//
// User Authentication Methods
//

//
// Retrieve Authentication status
//  -1 : Authentication Pending (This is set prior to any authentications)
//   0 : Authentication Failed (This will be set on any failure.  The app should try to re-authenticate if this is 0)
//   1 : The App/User is Authenticated
//
- (int) authStatus {
    return CWFAuthStatus;
}

- (int) connectWithUserPass:(NSString *)aUser emailAddr:(NSString *)aEmail password:(NSString *)aPass {
    NSURLConnection *conn;
    NSURL *url = [NSURL URLWithString:@"https://cwf.xcal.tv/care-wit-friends/api/v1/tokens"];
    
    NSLog(@"currentRequest: %@", currentRequest);
    if (([currentRequest isEqualToString:@"notAuthenticated"]) || ([currentRequest isEqualToString:@"authenticationFailed"])) {
        currentRequest = @"attemptingAuth";
    } else {
        // This should NEVER happen (we only authenticate once)
        currentRequest = @"authenticationCurrupted";
        return -100;
    }
    
    // Create the request.
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
    [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
    
    // Set Secure HTTP Request type
    [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
    // Specify that it will be a POST request
    [request setHTTPMethod:@"POST"];
    
    // This is how we set header fields
    [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    
    // Convert your data and set your request's HTTPBody property
    NSString *stringData = [NSString stringWithFormat:@"{\"username\":\"%@\",\"email\":\"%@\",\"password\":\"%@\"}", aUser, aEmail, aPass];
    NSLog(@"{\"username\":\"%@\",\"email\":\"%@\",\"password\":\"#########\"}", aUser, aEmail);
    NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:requestBodyData];
    
    // Fire request
    conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    return 1;
}

//
//
//  Delegate Methods to handle the NSURLConnections to the primary server
//
//

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    // A response has been received, this is where we initialize the instance var you created
    // so that we can append data to it in the didReceiveData method
    // Furthermore, this method is called each time there is a redirect so reinitializing it
    // also serves to clear it
    //    NSLog(@"DidReceiveResponse");
    _responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the new data to the instance variable you declared
    //    NSLog(@"DidReceiveData");
    [_responseData appendData:data];
    
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {
    // Return nil to indicate not necessary to store a cached response for this connection
    //    NSLog(@"willCacheResponses");
    return nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // The request is complete and data has been received
    // You can parse the stuff in your instance variable now
    NSLog(@"connectionDidFinishLoading");
    NSLog(@"Response Data: %@", [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding]);
    [self handleResponse];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    // The request has failed for some reason!
    // Check the error var
    NSLog(@"didFailWithError");
    NSLog(@"Error:\n%@", error);
    // At this point, we should examine the error and make a decision to resend the command or give up.
    
    currentRequest = @"authenticationFailed";
    CWFAuthStatus = 0;
}
@end


